package org.jin.jinaicode.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jin.jinaicode.annotation.AuthCheck;
import org.jin.jinaicode.common.BaseResponse;
import org.jin.jinaicode.common.ResultUtils;
import org.jin.jinaicode.constant.UserConstant;
import org.jin.jinaicode.exception.BusinessException;
import org.jin.jinaicode.exception.ErrorCode;
import org.jin.jinaicode.exception.ThrowUtils;
import org.jin.jinaicode.model.dto.history.ChatHistoryQueryDTO;
import org.jin.jinaicode.model.entity.User;
import org.jin.jinaicode.service.UserService;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.jin.jinaicode.model.entity.ChatHistory;
import org.jin.jinaicode.service.ChatHistoryService;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * 对话历史 控制层。
 *
 * @author 小堇
 */
@RestController
@RequestMapping("/chatHistory")
public class ChatHistoryController {

    @Resource
    private ChatHistoryService chatHistoryService;

    @Resource
    private UserService userService;

    /**
     * 分页查询某个应用的对话历史（游标查询）
     *
     * @param appId          应用ID
     * @param pageSize       页面大小
     * @param lastCreateTime 最后一条记录的创建时间
     * @param request        请求
     * @return 对话历史分页
     */
    @GetMapping("/app/{appId}")
    public BaseResponse<Page<ChatHistory>> listAppChatHistory(@PathVariable Long appId,
                                                              @RequestParam(defaultValue = "10") int pageSize,
                                                              @RequestParam(required = false) LocalDateTime lastCreateTime,
                                                              HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        Page<ChatHistory> result = chatHistoryService.listAppChatHistoryByPage(appId, pageSize, lastCreateTime, loginUser);
        return ResultUtils.success(result);
    }

    /**
     * 管理员分页查询所有对话历史
     *
     * @param chatHistoryQueryRequest 查询请求
     * @return 对话历史分页
     */
    @PostMapping("/admin/list/page/vo")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<ChatHistory>> listAllChatHistoryByPageForAdmin(@RequestBody ChatHistoryQueryDTO chatHistoryQueryRequest) {
        ThrowUtils.throwIf(chatHistoryQueryRequest == null, ErrorCode.PARAMS_ERROR);
        long pageNum = chatHistoryQueryRequest.getPageNum();
        long pageSize = chatHistoryQueryRequest.getPageSize();
        // 查询数据
        QueryWrapper queryWrapper = chatHistoryService.getQueryWrapper(chatHistoryQueryRequest);
        Page<ChatHistory> result = chatHistoryService.page(Page.of(pageNum, pageSize), queryWrapper);
        return ResultUtils.success(result);
    }

    /**
     * 导出应用对话记录为Markdown文件
     *
     * @param appId     应用ID
     * @param startTime 开始时间（可选）
     * @param endTime   结束时间（可选）
     * @param request   请求
     * @return Markdown文件下载
     */
    @GetMapping("/export/{appId}")
    @Operation(summary = "导出对话记录", description = "导出指定应用的对话记录为Markdown文件")
    public ResponseEntity<ByteArrayResource> exportChatHistory(@PathVariable Long appId,
                                                              @RequestParam(required = false) LocalDateTime startTime,
                                                              @RequestParam(required = false) LocalDateTime endTime,
                                                              HttpServletRequest request) {
        try {
            User loginUser = userService.getLoginUser(request);

            // 生成Markdown内容
            String markdownContent = chatHistoryService.exportChatHistoryToMarkdown(appId, startTime, endTime, loginUser);

            // 转换为字节数组
            byte[] bytes = markdownContent.getBytes(StandardCharsets.UTF_8);
            ByteArrayResource resource = new ByteArrayResource(bytes);

            // 生成文件名
            String fileName = generateFileName(appId, startTime, endTime);

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
            headers.add(HttpHeaders.CONTENT_TYPE, "text/markdown; charset=UTF-8");

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(bytes.length)
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "导出失败：" + e.getMessage());
        }
    }

    /**
     * 生成导出文件名
     */
    private String generateFileName(Long appId, LocalDateTime startTime, LocalDateTime endTime) {
        StringBuilder fileName = new StringBuilder();
        fileName.append("chat_history_app_").append(appId);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");

        if (startTime != null || endTime != null) {
            fileName.append("_");
            if (startTime != null) {
                fileName.append(startTime.format(formatter));
            } else {
                fileName.append("start");
            }
            fileName.append("_to_");
            if (endTime != null) {
                fileName.append(endTime.format(formatter));
            } else {
                fileName.append("end");
            }
        } else {
            fileName.append("_").append(LocalDateTime.now().format(formatter));
        }

        fileName.append(".md");
        return fileName.toString();
    }

}
